﻿using System;

namespace DimensionsHelper.Common.Metadata.Script;

/// <summary>
///     表达式中的整数值。
/// </summary>
public class ExpressionInteger : ExpressionBasicType
{
    /// <summary>
    ///     表达式中的整数值。
    /// </summary>
    public ExpressionInteger(int value) : base(BasicTypes.Integer)
    {
        Value = value;
    }

    /// <summary>
    ///     表达式整数值对应的具体数值。
    /// </summary>
    public int Value { get; }

    public override bool CanImplicitlyConvert(BasicTypes type)
    {
        return type == BasicTypes.Integer
               || type == BasicTypes.Boolean;
    }

    public override ExpressionBasicType ConvertTo(BasicTypes type)
    {
        switch (type)
        {
            case BasicTypes.Integer:
                return this;
            case BasicTypes.Double:
                return new ExpressionDouble(Value);
            case BasicTypes.String:
                return new ExpressionString(Value.ToString());
            case BasicTypes.Boolean:
                return new ExpressionBoolean(Value != 0);
            case BasicTypes.Categorical:
                return new Categorical(Value);
            default:
                throw ThrowHelper.TypeConvertFailed("Integer", type.ToString());
        }
    }

    public override object GetValue(BasicTypes type)
    {
        switch (type)
        {
            case BasicTypes.Integer:
                return Value;
            case BasicTypes.Double:
                return Convert.ToDouble(Value);
            case BasicTypes.String:
                return Value.ToString();
            case BasicTypes.Boolean:
                return Convert.ToBoolean(Value);
            default:
                throw ThrowHelper.TypeConvertFailed("Integer", type.ToString());
        }
    }

    public static ExpressionBasicType CreateExpressionNumber(object value)
    {
        switch (value)
        {
            case int integer:
                return new ExpressionInteger(integer);
            case double db:
                return new ExpressionDouble(db);
            default:
                throw new InvalidOperationException();
        }
    }

    public override ExpressionBasicType Add(ExpressionBasicType expression)
    {
        return CreateExpressionNumber(Calculate(expression, CalculateTypes.Add));
    }

    public override ExpressionBasicType Subtract(ExpressionBasicType expression)
    {
        return CreateExpressionNumber(Calculate(expression, CalculateTypes.Subtract));
    }

    public override ExpressionBasicType Multiply(ExpressionBasicType expression)
    {
        return CreateExpressionNumber(Calculate(expression, CalculateTypes.Multiply));
    }

    public override ExpressionBasicType Divide(ExpressionBasicType expression)
    {
        return CreateExpressionNumber(Calculate(expression, CalculateTypes.Divide));
    }

    public override ExpressionBasicType Modulo(ExpressionBasicType expression)
    {
        return CreateExpressionNumber(Calculate(expression, CalculateTypes.Modulo));
    }

    public override string ToString()
    {
        return Value.ToString();
    }
}